package com.notary.tx_live_plugin.widget;

import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.util.AttributeSet;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.notary.tx_live_plugin.util.TxConstant;
import com.notary.tx_live_plugin.util.TxLogger;
import com.notary.tx_live_plugin.util.TxLiveUtils;
import com.tencent.rtmp.ITXVodPlayListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXVodPlayConfig;
import com.tencent.rtmp.TXVodPlayer;
import com.tencent.rtmp.ui.TXCloudVideoView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 直播录像视频，根据url进行在线播放
 */
public class TxLivePlayView extends FrameLayout implements ITXVodPlayListener {
    private static final int PLAY_START = 0;
    private static final int PLAY_RUN = 1;
    private static final int PLAY_PAUSE = 2;
    private TXCloudVideoView mPlayerView;
    private TXVodPlayer mLivePlayer;
    private TXVodPlayConfig mPlayConfig;
    private List<String> mUrls;
    private String mCacheFilePath;
    private int playIndex;
    private int playingStatus;
    private long mStartPlayTS = 0;
    private OnPlayCallback mOnPlayCallback;
    private final HashMap<String,Object> mData = new HashMap<>();

    public TxLivePlayView(@NonNull Context context) {
        super(context);
        initView();
    }

    public TxLivePlayView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public TxLivePlayView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        mPlayerView = new TXCloudVideoView(getContext());
        mPlayConfig = new TXVodPlayConfig();
        mLivePlayer = new TXVodPlayer(getContext());
        addView(mPlayerView);
    }

    public void setOnPlayCallback(OnPlayCallback onPlayCallback) {
        this.mOnPlayCallback = onPlayCallback;
    }

    public boolean isPlaying() {
        return mLivePlayer.isPlaying() || PLAY_RUN == playingStatus;
    }

    public void startPlay(List<String> url,String cacheFilePath) {
        mUrls = url;
        mCacheFilePath = cacheFilePath;
        if(playingStatus != PLAY_START) {
            if (!mLivePlayer.isPlaying()) {
                //mBtnPlay.setImageResource(R.mipmap.paly_button_pause);
                mLivePlayer.resume();
                playingStatus = PLAY_RUN;
            } else {
                //mBtnPlay.setImageResource(R.mipmap.paly_button_paly);
                mLivePlayer.pause();
                playingStatus = PLAY_PAUSE;
            }
            setPlaying(playingStatus);
        } else if(TxLiveUtils.getNetworkType(getContext()) == ConnectivityManager.TYPE_WIFI){
            firstPlayRtmp();
        }else {
            callback(TxConstant.PlayMethod.Back.checkPlayForNotWifi,null);
        }
    }

    private void setPlaying(int playing){
        callback(TxConstant.PlayMethod.Back.playStatus,playing);
    }

    public void stopPlay() {
        stopPlayRtmp();
    }

    public void firstPlayRtmp() {
        if(mUrls == null || mUrls.size() == 0)return;
        playIndex = 0;
        playingStatus = PLAY_RUN;
        startPlayRtmp(mUrls.get(playIndex));
    }

    private void startPlayRtmp(String playUrl) {
        //mBtnPlay.setImageResource(R.mipmap.paly_button_pause);
        mLivePlayer.setPlayerView(mPlayerView);
        mLivePlayer.setVodListener(this);
        // mLivePlayer.setRate(1.5f);
        // 硬件加速在1080p解码场景下效果显著，但细节之处并不如想象的那么美好：
        // (1) 只有 4.3 以上android系统才支持
        // (2) 兼容性我们目前还仅过了小米华为等常见机型，故这里的返回值您先不要太当真
        mLivePlayer.enableHardwareDecode(false);
        mLivePlayer.setRenderRotation(TXLiveConstants.RENDER_ROTATION_PORTRAIT);
        mLivePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_ADJUST_RESOLUTION);
        //缓存设置 StorageUtil.getCacheDir().getAbsolutePath()
        String cache = mCacheFilePath != null ? mCacheFilePath : getContext().getExternalCacheDir().getAbsolutePath();
        mPlayConfig.setCacheFolderPath(cache);
        mPlayConfig.setMaxCacheItems(5);

        Map<String, String> header = new HashMap<>();
        mPlayConfig.setHeaders(header);
        mLivePlayer.setConfig(mPlayConfig);
        mLivePlayer.setAutoPlay(true);
        int result = mLivePlayer.startPlay(playUrl); // result返回值：0 success; -1// empty url;
        if (result != 0) {
            playingStatus = PLAY_START;
            setPlaying(playingStatus);
            callback(TxConstant.PlayMethod.Back.startPlay,false);
            //mBtnPlay.setImageResource(R.mipmap.paly_button_paly);
            // mRootView.setImageResource(R.drawable.main_bkg);
            return;
        }
        TxLogger.w("video render", "timetrack start play");
        startLoadingAnimation();

        mStartPlayTS = System.currentTimeMillis();
        callback(TxConstant.PlayMethod.Back.startPlay,true);
        playingStatus = PLAY_RUN;
        setPlaying(playingStatus);
    }

    private void startLoadingAnimation() {
        callback(TxConstant.PlayMethod.Back.startLoading,true);
    }

    private void stopLoadingAnimation() {
        callback(TxConstant.PlayMethod.Back.startLoading,false);
    }

    private void stopPlayRtmp() {
//        mBtnPlay.setImageResource(R.mipmap.paly_button_paly);
        stopLoadingAnimation();
        if (mLivePlayer != null) {
            mLivePlayer.setVodListener(null);
            mLivePlayer.stopPlay(true);
        }
        playingStatus = PLAY_START;
        setPlaying(playingStatus);
    }

    public void onPause() {
        if (playingStatus == PLAY_RUN) {
            mLivePlayer.pause();
        }
    }

    public void onResume() {
        if (playingStatus == PLAY_RUN) mLivePlayer.resume();
    }

    public void onDestroy() {
        if (mLivePlayer != null) {
            mLivePlayer.setVodListener(null);
            mLivePlayer.stopPlay(true);
            mLivePlayer = null;
        }
        if (mPlayerView != null) {
            mPlayerView.onDestroy();
            mPlayerView = null;
        }
    }

    /**
     * 更改播放进度
     * @param progress 单位 秒
     */
    public void seek(int progress){
        if(mLivePlayer != null) mLivePlayer.seek(progress);
    }

    private void callback(String method, Object data) {
        if (mOnPlayCallback != null) mOnPlayCallback.callback(method, data);
    }

    @Override
    public void onPlayEvent(TXVodPlayer txVodPlayer, int event, Bundle param) {
        String msg = param.getString(TXLiveConstants.EVT_DESCRIPTION);
        TxLogger.d(event, msg);
//        if(getActivity() == null || getActivity().isFinishing()){
//            Logger.d("live player is finish");
//            return;
//        }
        switch (event) {
            case TXLiveConstants.PLAY_EVT_PLAY_BEGIN:
                TxLogger.d("PlayFirstRender,cost=", (System.currentTimeMillis() - mStartPlayTS));
                stopLoadingAnimation();
                break;
            case TXLiveConstants.PLAY_EVT_PLAY_PROGRESS:
                int progress = param.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS);
                int duration = param.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS);
                int playable = param.getInt(TXLiveConstants.EVT_PLAYABLE_DURATION_MS);
                //mData.clear();
                mData.put(TxConstant.PlayMethod.Key.progress,progress);//mSeekBar.setProgress
                mData.put(TxConstant.PlayMethod.Key.duration,duration);//setMax
                mData.put(TxConstant.PlayMethod.Key.playable,playable);//setSecondaryProgress
                mData.put(TxConstant.PlayMethod.Key.startTime,TxLiveUtils.getFormatDuration(progress / 1000));
                mData.put(TxConstant.PlayMethod.Key.durationTime,TxLiveUtils.getFormatDuration(duration / 1000));
                //TxLogger.d(" progress ", progress, " secondary progress ", playable, duration);
                callback(TxConstant.PlayMethod.Back.playProcess,mData);
                break;
            case TXLiveConstants.PLAY_ERR_NET_DISCONNECT:
            case TXLiveConstants.PLAY_EVT_PLAY_END:
            case TXLiveConstants.PLAY_ERR_FILE_NOT_FOUND:
                stopPlayRtmp();
//                mTextStart.setText("00:00:00");
//                mSeekBar.setProgress(0);
                mData.clear();
                mData.put(TxConstant.PlayMethod.Key.progress,0);//mSeekBar.setProgress
                callback(TxConstant.PlayMethod.Back.playProcess,mData);
                //播放结束，如果证据有多个视频，则继续下一个证据视频播放
                if (event == TXLiveConstants.PLAY_EVT_PLAY_END) {
                    playIndex++;
                    if (playIndex >= mUrls.size()) {
                        callback(TxConstant.PlayMethod.Back.toast,"播放结束");
//                        ToastUtil.showMsg("播放结束");
//                        tips.setVisibility(View.VISIBLE);
                    } else {
                        startPlayRtmp(mUrls.get(playIndex));
                        callback(TxConstant.PlayMethod.Back.toast,"播放证据的下一个视频");
//                        ToastUtil.showMsg("播放证据的下一个视频");
                    }
                }
                break;
            case TXLiveConstants.PLAY_EVT_PLAY_LOADING:
            case TXLiveConstants.PLAY_WARNING_RECONNECT:
                startLoadingAnimation();
                break;
            case TXLiveConstants.PLAY_EVT_RCV_FIRST_I_FRAME:
                stopLoadingAnimation();
                break;
            case TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION:
                break;
            case TXLiveConstants.PLAY_ERR_HLS_KEY:
                stopPlayRtmp();
                break;
            default:
//                ToastUtil.showMsg(msg);
                break;
        }
    }

    @Override
    public void onNetStatus(TXVodPlayer txVodPlayer, Bundle status) {
//        TxLogger.d(" Current status CPU:" + status.getString(TXLiveConstants.NET_STATUS_CPU_USAGE)
//                + ", RES:" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_WIDTH)
//                + "*" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_HEIGHT)
//                + ", SPD:" + status.getInt(TXLiveConstants.NET_STATUS_NET_SPEED) + "Kbps"
//                + ", FPS:" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_FPS)
//                + ", ARA:" + status.getInt(TXLiveConstants.NET_STATUS_AUDIO_BITRATE) + "Kbps"
//                + ", VRA:" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_BITRATE) + "Kbps");
    }

    public interface OnPlayCallback {
        void callback(String methodName, Object data);
    }
}
